home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / comm / revrdist.sit / RevRdist / RevRdist src / simpledialog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-11-04  |  11.1 KB  |  389 lines  |  [TEXT/KAHL]

  1. /*
  2.     Present a dialog box with a text rectangle, a scroll bar, and an OK
  3.     button.  This can be used as a help dialog.  Pass in a dialog
  4.     resource number and a handle to the text.  The dialog should
  5.     have the OK button as the first item, and user items for the
  6.     second and third items.  The second is the rect in which the
  7.     control is drawn, the third is the rect in which text is drawn.
  8.     Only the OK button should be enabled.
  9.  
  10.     The text handle should be locked before calling TextDlog and
  11.     unlocked after.
  12.  
  13.     Original author:                    dubois@uwmacc.UUCP (Paul DuBois)
  14.     with a few changes & cleanup by:    blob@apple.com  (Brian Bechtel)
  15. */
  16.  
  17. #include   <EventMgr.h>
  18. #include   <DialogMgr.h>
  19. #include   <ControlMgr.h>
  20.  
  21.  
  22. #define    nil     0L
  23.  
  24. #define ETX 03      /* Enter key */
  25. #define CR  13      /* Return key */
  26.  
  27. enum        /* item numbers */
  28. {
  29.     OKButton = 1,
  30.     scrollBarUser,
  31.     textRectUser
  32. };
  33.  
  34. static ControlHandle    theScroll;
  35. static Boolean          needScroll; /* true if need scroll bar */
  36. static int              curLine;
  37. static int              halfPage;
  38. static TEHandle         teHand;
  39.  
  40. static void HighLightDefault(DialogPtr dPtr);
  41. static pascal void DrawScroll (DialogPtr theDialog, int itemNo);
  42. static pascal void DrawTextRect (DialogPtr theDialog, int itemNo);
  43. static void DoScroll (int lDelta);
  44. static pascal void __TrackScroll (ControlHandle theScroll, int partCode);
  45. static pascal Boolean TextFilter (DialogPtr theDialog,
  46.                     EventRecord *theEvent, int *itemHit);
  47. void TextDialog (int dlogNum,Handle textHandle,int fontNum,int fontSize,
  48.                     Boolean wrap);
  49.  
  50.  
  51.  
  52. /************************************************************************
  53.  *
  54.  *  Function:       HighLightDefault
  55.  *
  56.  *  Purpose:        highlight the default button in a dialog
  57.  *
  58.  *  Returns:        nothing
  59.  *
  60.  *  Side Effects:   standard box is drawn around highlight box
  61.  *
  62.  *  Description:    draws the heavy rounded box around the OK button,
  63.  *                  so that the user knows that hitting enter or return
  64.  *                  is the same as pressing the OK button.
  65.  *
  66.  ************************************************************************/
  67. static void
  68. HighLightDefault(dPtr)
  69. DialogPtr dPtr;
  70. {
  71.     int unusedItemType;
  72.     Handle unusedItemHandle;
  73.     Rect box;
  74.     PenState p;
  75.  
  76.     /*  This next little piece of code puts the default heavy rounded
  77.         box around the "OK" button, so the user knows that pressing
  78.         return is the same as hitting "OK"
  79.     */
  80.     SetPort(dPtr);      /* without this, can't highlite OK */
  81.     GetDItem(dPtr, OKButton, &unusedItemType, &unusedItemHandle, &box);
  82.     GetPenState(&p);
  83.     PenSize(3,3);
  84.     InsetRect(&box, -4, -4);
  85.     FrameRoundRect(&box, 16, 16);
  86.     PenSize(p.pnSize.h, p.pnSize.v);
  87. }
  88.  
  89. /************************************************************************
  90.  *
  91.  *  Function:       DrawScroll
  92.  *
  93.  *  Purpose:        draw scroll bar user item
  94.  *
  95.  *  Returns:        nothing
  96.  *
  97.  *  Side Effects:   draws scroll bar user item
  98.  *
  99.  *  Description:    if we need to scroll, show the control.
  100.  *
  101.  ************************************************************************/
  102. static pascal void DrawScroll (theDialog, itemNo)
  103. DialogPtr   theDialog;
  104. int         itemNo;
  105. {
  106.     if (needScroll)
  107.         ShowControl (theScroll);
  108. }
  109.  
  110.  
  111. /*
  112.     Proc for drawing text display user item.
  113. */
  114.  
  115.  
  116. /************************************************************************
  117.  *
  118.  *  Function:       DrawTextRect
  119.  *
  120.  *  Purpose:        draw text display user item
  121.  *
  122.  *  Returns:        nothing
  123.  *
  124.  *  Side Effects:   shows the text
  125.  *
  126.  *  Description:    Get the rectangle for our text.  If we need to scroll,
  127.  *                  frame the rectangle so that it will look correct.
  128.  *                  Get the view rectangle of our text rectangle, and do
  129.  *                  a TEUpdate so that text edit will properly handle
  130.  *                  updating the rectangle.
  131.  *
  132.  ************************************************************************/
  133. static pascal void DrawTextRect (theDialog, itemNo)
  134. DialogPtr   theDialog;
  135. int         itemNo;
  136. {
  137. Rect    r;
  138. int     itemType;
  139. Handle  itemHandle;
  140.  
  141.     GetDItem (theDialog, textRectUser, &itemType, &itemHandle, &r);
  142.     if (needScroll)
  143.         FrameRect (&r);
  144.     r = (**teHand).viewRect;
  145.     TEUpdate (&r, teHand);
  146. }
  147.  
  148.  
  149. /************************************************************************
  150.  *
  151.  *  Function:       DoScroll
  152.  *
  153.  *  Purpose:        scroll to correct position
  154.  *
  155.  *  Returns:        nothing.
  156.  *
  157.  *  Side Effects:   text is scrolled to new position
  158.  *
  159.  *  Description:
  160.  *                  Scroll to the correct position.  lDelta is the
  161.  *                  amount to CHANGE the current scroll setting by.
  162.  *
  163.  ************************************************************************/
  164. static void
  165. DoScroll (lDelta)
  166. int     lDelta;
  167. {
  168. int newLine;
  169.  
  170.     newLine = curLine + lDelta;
  171.     if (newLine < 0) newLine = 0;
  172.     if (newLine > GetCtlMax (theScroll)) newLine = GetCtlMax (theScroll);
  173.     SetCtlValue (theScroll, newLine);
  174.     lDelta = (curLine - newLine ) * (**teHand).lineHeight;
  175.     TEScroll (0, lDelta, teHand);
  176.     curLine = newLine;
  177. }
  178.  
  179.  
  180.  
  181. /************************************************************************
  182.  *
  183.  *  Function:       __TrackScroll
  184.  *
  185.  *  Purpose:        track the scrolling
  186.  *
  187.  *  Returns:        nothing
  188.  *
  189.  *  Side Effects:   scrolling
  190.  *
  191.  *  Description:    get the control part that we're in.  If we're still
  192.  *                  in the same part, we're going to scroll.  Check what
  193.  *                  kind of part we're in, and set our delta accordingly.
  194.  *                  Call DoScroll to actually handle the scrolling.
  195.  *
  196.  ************************************************************************/
  197. static pascal void __TrackScroll (theScroll, partCode)
  198. ControlHandle   theScroll;
  199. int             partCode;
  200. {
  201. int lDelta;
  202.  
  203.     if (partCode == GetCRefCon (theScroll)) /* still in same part? */
  204.     {
  205.         switch (partCode)
  206.         {
  207.             case inUpButton: lDelta = -1; break;
  208.             case inDownButton: lDelta = 1; break;
  209.             case inPageUp: lDelta = -halfPage; break;
  210.             case inPageDown: lDelta = halfPage; break;
  211.         }
  212.         DoScroll (lDelta);
  213.     }
  214. }
  215.  
  216.  
  217. /*
  218.     Filter to handle hits in scroll bar
  219. */
  220.  
  221.  
  222. /************************************************************************
  223.  *
  224.  *  Function:       TextFilter
  225.  *
  226.  *  Purpose:        filter to handle hits in scroll bar
  227.  *
  228.  *  Returns:        false (indicating we should continue within our
  229.  *                  modal dialog)
  230.  *
  231.  *  Side Effects:   May scroll the text
  232.  *
  233.  *  Description:    We're being called as part of a ModalDialog call.
  234.  *                  Check what kind of event activated us.  If it was a
  235.  *                  mouseDown, handle it.  If we were in the thumb, track
  236.  *                  the thumb, otherwise scroll the indicated amount.
  237.  *
  238.  ************************************************************************/
  239. static pascal Boolean TextFilter (theDialog, theEvent, itemHit)
  240. DialogPtr   theDialog;
  241. EventRecord *theEvent;
  242. int         *itemHit;
  243. {
  244. Point   thePoint;
  245. int     thePart;
  246. Boolean result;
  247.  
  248.     result = false;
  249.     switch (theEvent->what)
  250.     {
  251.         case mouseDown:
  252.             thePoint = theEvent->where;
  253.             GlobalToLocal (&thePoint);
  254.             thePart = TestControl (theScroll, thePoint);
  255.             if (thePart == inThumb)
  256.             {
  257.                 (void) TrackControl (theScroll, thePoint, nil);
  258.                 DoScroll (GetCtlValue (theScroll) - curLine);
  259.             }
  260.             else if (thePart != 0)
  261.             {
  262.                 SetCRefCon (theScroll, (long) thePart);
  263.                 (void) TrackControl (theScroll, thePoint, __TrackScroll);
  264.             }
  265.             break;
  266.         case keyDown:
  267.             if ((theEvent->message & charCodeMask) == ETX)
  268.             {
  269.                 *itemHit = 1;
  270.                 result = true;
  271.             }
  272.             if ((theEvent->message & charCodeMask) == CR)
  273.             {
  274.                 *itemHit = 1;
  275.                 result = true;
  276.             }
  277.             break;
  278.         case updateEvt:
  279.         case activateEvt:
  280.             HighLightDefault(theDialog);
  281.             break;
  282.     }
  283.     return (result);
  284. }
  285.  
  286.  
  287.  
  288. /************************************************************************
  289.  *
  290.  *  Function:       TextDialog
  291.  *
  292.  *  Purpose:        put up text dialog with optional scroll bar
  293.  *
  294.  *  Returns:        nothing
  295.  *
  296.  *  Side Effects:   none
  297.  *
  298.  *  Description:    Pass in a dialog number, a handle to the text to
  299.  *                  display, a font number, font size, and a boolean
  300.  *                  indicating whether you want the text to wrap or not.
  301.  *
  302.  *                  The dialog referenced by dlogNum should have the 
  303.  *                  OK button as the first item, and user items for the
  304.  *                  second and third items.  The second is the rect in
  305.  *                  which the control is drawn, the third is the rect in
  306.  *                  which text is drawn. Only the OK button should be
  307.  *                  enabled.
  308.  *
  309.  *                  The text handle should be locked before calling us,
  310.  *                  and unlocked afterwards.
  311.  *
  312.  *                  Of course, the font number and size should exist in
  313.  *                  the current system, or it will default to something
  314.  *                  ugly.
  315.  *
  316.  ************************************************************************/
  317. void
  318. TextDialog (dlogNum, textHandle, fontNum, fontSize, wrap)
  319. int     dlogNum;
  320. Handle  textHandle;
  321. int     fontNum;
  322. int     fontSize;
  323. Boolean wrap;
  324. {
  325. GrafPtr     oldPort;
  326. DialogPtr   theDialog;
  327. int         itemNo;
  328. int         itemType;
  329. Handle      itemHandle;
  330. Rect        r;
  331. int         scrollLines;
  332. int         viewLines;
  333. Handle      oldHText;
  334. ProcPtr     filterProc = nil;
  335.  
  336.     GetPort (&oldPort);
  337.     theDialog = GetNewDialog (dlogNum, nil, -1L);
  338.     if (!theDialog)
  339.         return;
  340.  
  341.     GetDItem (theDialog, textRectUser, &itemType, &itemHandle, &r);
  342.     SetDItem (theDialog, textRectUser, itemType, DrawTextRect, &r);
  343. /*
  344.     incorporate text into a TERec.
  345. */
  346.     SetPort (theDialog);
  347.     TextFont (fontNum);
  348.     TextSize (fontSize);
  349.  
  350.     InsetRect (&r, 4, 4);
  351.     teHand = TENew (&r, &r);
  352.     if (!wrap)
  353.         (**teHand).crOnly = -1;
  354.     oldHText = (**teHand).hText;        /* save this.  restore later */
  355.     (**teHand).hText = textHandle;
  356.     TECalText (teHand);
  357.     viewLines = (r.bottom - r.top) / (**teHand).lineHeight;
  358.     scrollLines = (**teHand).nLines - viewLines;
  359.     needScroll = (scrollLines > 0);
  360.     GetDItem (theDialog, scrollBarUser, &itemType, &itemHandle, &r);
  361.     SetDItem (theDialog, scrollBarUser, itemType, DrawScroll, &r);
  362.     if (needScroll)
  363.     {
  364.         theScroll = NewControl (theDialog, &r, "\p", false, 0, 0, 0,
  365.                         scrollBarProc, nil);
  366.         SetCtlMax (theScroll, scrollLines);
  367.         halfPage = viewLines / 2;
  368.         curLine = 0;
  369.         filterProc = (ProcPtr) TextFilter;
  370.     }
  371.  
  372.     ShowWindow (theDialog);
  373.     HighLightDefault (theDialog);
  374.  
  375.     do {
  376.         ModalDialog (filterProc, &itemNo);
  377.     } while (itemNo != OKButton);
  378.  
  379. /*
  380.     restore hText field of TE record before disposing of it.
  381. */
  382.     (**teHand).hText = oldHText;
  383.     TEDispose (teHand);
  384.  
  385.     if (needScroll)
  386.         DisposeControl (theScroll);
  387.     SetPort (oldPort);
  388.     DisposDialog(theDialog);
  389. }